#ifndef REMOTE_CLIENT_CLIENT_CONTROL_SESSION_H_
#define REMOTE_CLIENT_CLIENT_CONTROL_SESSION_H_

#include "vzconn/conn/tcpconnect.h"
#include "vzconn/conn/vzclient.h"
#include "remote/stanza/querystanza.h"

namespace remote {

class ClientControlSession : public boost::noncopyable,
  public boost::enable_shared_from_this < ClientControlSession > {
 public:
  typedef boost::shared_ptr<ClientControlSession> Ptr;

  ClientControlSession(boost::asio::io_service &io_service,
                       const std::string base_name);
  virtual ~ClientControlSession();

  boost::signals2::signal<void(
    ClientControlSession::Ptr session,
    uint32 error_code)> SignalConnectFailure;

  boost::signals2::signal<void(
    ClientControlSession::Ptr session)> SignalConnectSucceed;

  boost::signals2::signal<void(
    ClientControlSession::Ptr session,
    QueryStanza::Ptr stanza)> SignalSessionMessage;


  bool Start(const char *server_addr, uint16 port);
  void Stop();

  bool AsyncWrite(QueryStanza::Ptr stanza);

  const std::string session_name() {
    return session_name_;
  }
  const std::string server_name() {
    return server_name_;
  }
 private:
  void OnConnectEvent(vzconn::VzConnect::Ptr connect,
                      const boost::system::error_code& err);
  void OnConnectError(vzconn::VzConnect::Ptr connect,
                      const boost::system::error_code& err);
  void OnConnectWrite(vzconn::VzConnect::Ptr connect);
  void OnConnectRead(vzconn::VzConnect::Ptr connect,
                     const char* buffer, int size, int flag);

  void StartRegisterClient();
  void ProcessRegisterMessage(QueryStanza::Ptr stanza);
 private:
  boost::asio::io_service &io_service_;
  vzconn::VzConnect::Ptr control_connect_;
  std::string session_name_;
  std::string server_name_;
};

}

#endif  // REMOTE_CLIENT_CLIENT_CONTROL_SESSION_H_
